use anyhow::anyhow;

fn main() -> anyhow::Result<()> {
    // let ans = f3(f2(f1("Hello")?)?)?;
    let ans = xtry!(f3(xtry!(f2(xtry!(f1("hello"))))));
    println!("Final ans: {}", ans);
    Ok(())
}

fn f1(s: impl AsRef<str>) -> anyhow::Result<String> {
    Ok(format!("f1: {}", s.as_ref()))
}

fn f2(s: impl AsRef<str>) -> anyhow::Result<String> {
    Ok(format!("f2: {}", s.as_ref()))
}

fn f3(s: impl AsRef<str>) -> anyhow::Result<String> {
    Err(anyhow!("f3: {}", s.as_ref()))
}

#[macro_export]
macro_rules! xtry {
    ($expr: expr) => {
        match $expr {
            Ok(val) => val,
            Err(err) => return Err(err.into()),
        }
    };
}
